import { defineBoot } from '#q-app/wrappers';
import axios from 'axios';

import { LocalStorage, Notify } from 'quasar';
import { useLocalStorage } from '@vueuse/core';

// Be careful when using SSR for cross-request state pollution
// due to creating a Singleton instance here;
// If any client changes this (global) instance, it might be a
// good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually
// for each client)
const api = axios.create({ baseURL: 'http://localhost:3000' });

export default defineBoot(({ app }) => {
  // for use inside Vue files (Options API) through this.$axios and this.$api
  api.interceptors.request.use(
    (request) => {
      const token = useLocalStorage('token', '');
      request.headers = {
        'Content-Type': 'application/json;charset=utf-8',
        authorization: `Bearer ${token.value}`,
      };
      return request;
    },
    (error) => {
      Notify.create({
        type: 'negative',
        message: error,
        position: 'top',
      });
      return Promise.reject(error);
    },
  );
  api.interceptors.response.use(
    (response) => {
      const codeMap = {
        200: () => {
          return response.data;
        },
        401: () => {
          Notify.create({
            type: 'negative',
            message: response.data.msg || '未授权',
            position: 'top',
          });
          LocalStorage.remove('token');
          app.$router.push({ name: 'Login' });
          return Promise.reject(response.data);
        },
        500: () => {
          Notify.create({
            type: 'negative',
            message: response.data.msg || '服务器内部错误',
            position: 'top',
          });
          return Promise.reject(response.data);
        },
      };
      const code = response.data.code;
      return typeof codeMap[code] === 'function'
        ? codeMap[code]()
        : (() => {
            Notify.create({
              type: 'negative',
              message: response.data.msg || '未知错误',
              position: 'top',
            });
            return Promise.reject(response.data);
          })();
    },
    (error) => {
      // 500
      // if (error + '' === 'Error: Request failed with status code 500') {
      //   Dialog.create({
      //     title: i18n.global.t('Error'),
      //     message:
      //       i18n.global.t('Data') +
      //       i18n.global.t('Exception') +
      //       ',' +
      //       i18n.global.t('Please') +
      //       i18n.global.t('Relogin'),
      //     persistent: true,
      //     ok: {
      //       push: true,
      //       color: 'negative',
      //       label: i18n.global.t('Logout'),
      //     },
      //   }).onOk(() => {
      //     userStore.HandleLogout()
      //     router.push({ name: 'login' })
      //   })
      // }
      // // timeout
      // if (error + '' === 'Error: timeout of 40000ms exceeded') {
      //   Notify.create({
      //     type: 'negative',
      //     message: i18n.global.t('Operation') + i18n.global.t('Timeout'),
      //   })
      // }
      // // network error
      // if (error + '' === 'Error: Network Error') {
      //   router.push({ name: 'notFound' })
      // } else if (error.response && error.response.status === 404) {
      //   Notify.create({
      //     type: 'negative',
      //     message:
      //       i18n.global.t('Request') +
      //       i18n.global.t('Address') +
      //       i18n.global.t('NotFound') +
      //       ' ' +
      //       error.response.request.responseURL,
      //   })
      // }
      return Promise.reject(error);
    },
  );
  app.config.globalProperties.$axios = axios;
  // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
  //       so you won't necessarily have to import axios in each vue file
  app.config.globalProperties.$api = api;
  // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form)
  //       so you can easily perform requests against your app's API
});

export { api };
